package org.game.module.datingbo;

import com.google.common.collect.Maps;
import com.sojoys.artifact.tools.SK_String;
import com.sojoys.artifact.tools.ToolMap;
import org.cfg.DiscreteDataCfg;
import org.cfg.cache.DiscreteDataCfgCache;
import org.constant.DiscreteDataID;
import org.constant.DiscreteDataKey;

import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 预定约会规则
 * Created by fxf on 2017/11/10.
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class ReserveDatingRule {

    /**
     * 邀请时间段
     */
    private static final String INVITATION_TIME_FRAME = "itf";

    /**
     * 约会时间段
     */
    private static final String DATING_TIME_FRAME = "dtf";

    /**
     * 该时间段最大约会次数（接受约会邀请次数）
     */
    private static final String MAX_DATING_COUNT = "mtc";


    /**
     * 每个看板娘每天可以触发的预定约会次数
     */
    private static int roleDayDatingCount;

    private static Map<int[], Map> invitationTimeFrameMapping = Maps.newHashMap();

    private static Map<int[], Map> datingTimeFrameMapping = Maps.newHashMap();

    public static void loadRule() {
        DiscreteDataCfg cfg = DiscreteDataCfgCache.me().getById(DiscreteDataID.DATING);
        if (cfg == null) {
            return;
        }
        List<Map> list = ToolMap.getList("timeFrame", cfg.getData());
        list.forEach(map -> {
            int[] invitationTimeFrame = SK_String.StringToIntArray((String) map.get(DiscreteDataKey.DATING_INVITATION_TIME_FRAME), ',');
            int[] datingTimeFrame = SK_String.StringToIntArray((String) map.get(DiscreteDataKey.DATING_DATING_TIME_FRAME), ',');
            int maxDatingCount = (int) map.get(DiscreteDataKey.DATING_MAX_DATING_COUNT);
            Map valueMap = Maps.newHashMap();
            valueMap.put(INVITATION_TIME_FRAME, invitationTimeFrame);
            valueMap.put(DATING_TIME_FRAME, datingTimeFrame);
            valueMap.put(MAX_DATING_COUNT, maxDatingCount);
            invitationTimeFrameMapping.put(invitationTimeFrame, valueMap);
            datingTimeFrameMapping.put(datingTimeFrame, valueMap);
        });
        roleDayDatingCount = (int) cfg.getData().get(DiscreteDataKey.DATING_RESERVE_ROLE_DAY_DATING_COUNT);
    }


    /**
     * 根据约会时间段获取该时间段最大约会次数
     */
    public static int getMaxDatingCount(int[] datingTimeFrame) {
        Map map = datingTimeFrameMapping.get(datingTimeFrame);
        if (map != null) {
            return (int) map.get(MAX_DATING_COUNT);
        }
        return 0;
    }


    /**
     * 每个看板娘每天可以出发的预定约会次数
     */
    public static int getRoleDayDatingCount() {
        return roleDayDatingCount;
    }

    /**
     * 获取约会时间段
     */
    public static int[] getDatingTimeFrame() {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.MILLISECOND,0);
        for (int[] timeFrame : invitationTimeFrameMapping.keySet()) {
            Calendar beginTime = Calendar.getInstance();
            beginTime.set(Calendar.HOUR_OF_DAY, timeFrame[0]);
            beginTime.set(Calendar.MINUTE, timeFrame[1]);
            beginTime.set(Calendar.MILLISECOND, 0);

            Calendar endTime = Calendar.getInstance();
            endTime.set(Calendar.HOUR_OF_DAY, timeFrame[2]);
            endTime.set(Calendar.MINUTE, timeFrame[3]);
            endTime.set(Calendar.MILLISECOND, 0);
            
            if (beginTime.getTimeInMillis() <= now.getTimeInMillis() && endTime.getTimeInMillis() >= now.getTimeInMillis())
                return (int[]) invitationTimeFrameMapping.get(timeFrame).get(DATING_TIME_FRAME);
        }
        return null;
    }
    
    
    /**
     * 获取约会时间段，仅测试时使用
     */
    public static int[] getDatingTimeFrame4Test() {
        Calendar now = Calendar.getInstance();
        for (int[] timeFrame : invitationTimeFrameMapping.keySet()) {
            Calendar beginTime = Calendar.getInstance();
            beginTime.set(Calendar.HOUR_OF_DAY, timeFrame[0]);
            beginTime.set(Calendar.MINUTE, timeFrame[1]);
            beginTime.set(Calendar.MILLISECOND, 0);

            Calendar endTime = Calendar.getInstance();
            endTime.set(Calendar.HOUR_OF_DAY, timeFrame[2]);
            endTime.set(Calendar.MINUTE, timeFrame[3]);
            endTime.set(Calendar.MILLISECOND, 0);

            if (beginTime.getTimeInMillis()<now.getTimeInMillis() && endTime.getTimeInMillis()>now.getTimeInMillis()
                    ||beginTime.getTimeInMillis()==now.getTimeInMillis()
                    ||endTime.getTimeInMillis()==now.getTimeInMillis())
                return (int[]) invitationTimeFrameMapping.get(timeFrame).get(DATING_TIME_FRAME);
        }
        return null;

    } 

    /**
     * 当前时间是否在某个邀请时间段内，如果是则返回该时间段
     */
    public static int[] getInvitationTimeFrame() {
        Calendar now = Calendar.getInstance();
        for (int[] timeFrame : invitationTimeFrameMapping.keySet()) {
            Calendar beginTime = Calendar.getInstance();
            beginTime.set(Calendar.HOUR_OF_DAY, timeFrame[0]);
            beginTime.set(Calendar.MINUTE, timeFrame[1]);
            beginTime.set(Calendar.MILLISECOND, 0);

            Calendar endTime = Calendar.getInstance();
            endTime.set(Calendar.HOUR_OF_DAY, timeFrame[2]);
            endTime.set(Calendar.MINUTE, timeFrame[3]);
            endTime.set(Calendar.MILLISECOND, 0);

            if (beginTime.getTimeInMillis() <= now.getTimeInMillis() && endTime.getTimeInMillis() >= now.getTimeInMillis())
                return timeFrame;
        }
        return null;
    }

    /**
     * 是否约会时间点
     */
    public static boolean isDatingTimeFrame(int minute){
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        datingTimeFrameMapping.keySet().forEach(timeFrame->{
            for (int i = 0; i < timeFrame.length; ) {
                int beginTime = timeFrame[i++];
                int endTime = timeFrame[i++];
                if (beginTime == minute || endTime == minute){
                    atomicBoolean.set(true);
                    return;
                }
            }
        });
        return atomicBoolean.get();
    }

}